/******************************************************************************
	This file is a part of the Snapshot Bioinformatics Project

	Copyright (C) 2012-2013 Jarom Schow

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "SnapshotFileLoader.h"

#include <QtWidgets/QApplication>

#include "FileUtil.h"
#include "GenBankParser.h"
#include "GzFile.h"
#include "Progress.h"

#include "Snapshot.h"

/**
**/
SnapshotFileLoader::SnapshotFileLoader( Bio::SeqDatabase &seqDB ) : m_seqDB( seqDB )
{
}

/**
**/
SnapshotFileLoader::~SnapshotFileLoader()
{
}

/**
**/
bool SnapshotFileLoader::addFile( const QUrl &file )
{
	m_downloads.append( file );

	return true;
}

/**
**/
bool SnapshotFileLoader::loadAllFiles()
{
	bool				status = true;
	Bio::Progress		progress( "Downloading GenBank Files...", m_downloads.count() * 2 );
	QListIterator<QUrl>	downloadIt( m_downloads );
	QStringList			files;

	while( status && downloadIt.hasNext() ){
		QUrl				url = downloadIt.next();
		QString				filename = g_snapshot->getTempPath() + "/" + Bio::FileUtil::getFilename( url.path() );
		Bio::FileDownload	file( filename );

		files.append( filename );
	
		status = file.downloadSynchronous( url );

		progress.step();
	}

	if( !status ){
		progress.finish();
		return status;
	}

	progress.status( "Loading GenBank Files into database..." );

	QStringListIterator	fileIt( files );

	while( status && fileIt.hasNext() ){
		status = loadFile( fileIt.next() );
		progress.step();
	}

	progress.finish();

	return status;
}

/**
**/
bool SnapshotFileLoader::loadFile( const QString &filename )
{
	bool				status = true;
	Bio::GenBankParser	parser;
	QTime				timer;

	Bio::Core::log( "Reading sequence file " + filename );

	timer.start();

	if( filename.right( 3 ).toLower() == ".gz" ){
		Bio::GzFile	file( filename );
		if( !file.open( QIODevice::ReadOnly ) ){
			QString	msg = QString( "Could not open file '%1' for reading." ).arg( filename );

			Bio::Core::log( msg );
			return false;
		}
		status = parser.parse( file );
		file.close();
	}
	else {
		QFile	file( filename );
		if( !file.open( QIODevice::ReadOnly ) ){
			QString	msg = QString( "Could not open file '%1' for reading." ).arg( filename );

			Bio::Core::log( msg );
			return false;
		}
		status = parser.parse( file );
		file.close();
	}

	int elapsed1 = timer.elapsed() / 100;
	int	nRecords = parser.getNumRecords();

	if( status ){
		Bio::Core::log( QString( "%1 records read from file in %2 min %3.%4 sec." ).arg( nRecords )
			.arg( elapsed1 / 600 ).arg( (elapsed1 % 600) / 10 ).arg( elapsed1 % 10 ) );
	}
	else {
		Bio::Core::log( "Error reading file." );
		return false;
	}

	if( !m_seqDB.isValid() ){
		Bio::Core::log( "Error loading records: the sequence database is not valid." );
		return false;
	}

	Bio::Core::log( "Loading records into database..." );

	timer.restart();

	status = m_seqDB.load( &parser );
	if( !status ){
		Bio::Core::log( "Error loading records into database." );
		return false;
	}

	int	elapsed2 = timer.elapsed() / 100;

	Bio::Core::log( QString( "Loaded %1 records into database in %2 min %3.%4 sec." ).arg( nRecords )
		.arg( elapsed2 / 600 ).arg( (elapsed2 % 600) / 10 ).arg( elapsed2 % 10 ) );

	return true;
}
